/**
 * @SimpleClientSenderController.java  COPYRIGHT xiaojian
 * 
 * Created on 2016年7月20日 上午10:57:40
 */
package xiaojian.toolkit.netty.transport;

import java.util.List;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;

import xiaojian.toolkit.base.Sender;
import xiaojian.toolkit.bean.AbstractCommonBean;

/**
 * 一个简单的，用来控制Sender的对象。 随机从Sender列表中挑选一个Sender进行发送，如果发送失败，继续挑选，直到最大失败次数。
 * 
 * @author <a href="mailto:cxj2000@gmail.com">xiaojian.cao</a>
 *
 */
public class SimpleClientSenderController implements ClientSenderController {

	private static final Logger logger = LoggerFactory.getLogger(SimpleClientSenderController.class);

	private List<Sender<AbstractCommonBean>> senders = Lists.newCopyOnWriteArrayList();

	/**
	 * 最大尝试发送次数。
	 */
	private int maxSendRetryCount = 5;

	public int getMaxSendRetryCount() {
		return maxSendRetryCount;
	}

	public void setMaxSendRetryCount(int maxSendRetryCount) {
		this.maxSendRetryCount = maxSendRetryCount;
	}

	@Override
	public void send(AbstractCommonBean msg) {
		Preconditions.checkArgument(msg != null);

		for (int i = 0; i < maxSendRetryCount; i++) {
			int random = new Random().nextInt(senders.size());

			Sender<AbstractCommonBean> sender = senders.get(random);

			try {
				sender.send(msg);
				break;
			} catch (Exception exception) {
				logger.error("Cannot send msg[{}], exception[{}], recycle[{}]", msg, exception, i);
			}
		}
	}

	@Override
	public void setSenders(List<Sender<AbstractCommonBean>> sender) {
		if (sender == null || sender.size() == 0) {
			return;
		}

		senders.addAll(sender);
	}

	@Override
	public void addSender(Sender<AbstractCommonBean> sender) {
		Preconditions.checkArgument(sender != null);

		senders.add(sender);
	}

	@Override
	public void removeSender(Sender<AbstractCommonBean> sender) {
		Preconditions.checkArgument(sender != null);

		senders.remove(sender);
	}

	@Override
	public void send(Object req, AbstractCommonBean response) {
		this.send(response);
	}

}
